﻿// <copyright file="AppXamlUpdater.cs" company="Microsoft Corporation">
// Copyright (c) 2009 Microsoft Corporation All Rights Reserved
// </copyright>
// <author>Michael S. Scherotter</author>
// <email>mischero@microsoft.com</email>
// <date>2010-01-20</date>
// <summary>AppXamlUpdater class definition</summary>

namespace WebAnalyticsServiceWizard
{
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    using EnvDTE;

    /// <summary>
    /// Application XAML Updater Wizard utility class
    /// </summary>
    internal sealed class AppXamlUpdater
    {
        /// <summary>
        /// Modify the App.xaml for the active project
        /// </summary>
        /// <param name="automationObject">the Developer environment</param>
        public static void ModifyAppXaml(object automationObject)
        {
            var dte = automationObject as _DTE;

            var projectName = dte.SelectedItems.Item(1).Project.Name;

            ModifyAppXaml(automationObject, projectName);
        }

        /// <summary>
        /// Modify the App.xaml for a project
        /// </summary>
        /// <param name="automationObject">the developer environment</param>
        /// <param name="projectName">the active project name</param>
        public static void ModifyAppXaml(object automationObject, string projectName)
        {
            var dte = automationObject as _DTE;

            var projectObjects = dte.ActiveSolutionProjects as object[];

            var projects = projectObjects.Cast<Project>();

            var selectedProject = (from project in projects
                                   where project.Name == projectName
                                   select project).FirstOrDefault();

            var appXaml = (from item in selectedProject.ProjectItems.Cast<ProjectItem>()
                            where item.Name == "App.xaml"
                            select item).FirstOrDefault();

            if (appXaml == null)
            {
                System.Diagnostics.Debug.WriteLine("App.xaml was not found in this project.");

                return;
            }

            var window = appXaml.Open(Constants.vsViewKindTextView);

            var textDocument = window.Document.Object("TextDocument") as TextDocument;

            var startPoint = textDocument.StartPoint.CreateEditPoint();

            var text = startPoint.GetText(textDocument.EndPoint);

            var doc = XDocument.Parse(text, LoadOptions.PreserveWhitespace);

            XNamespace mwa = "clr-namespace:Microsoft.WebAnalytics;assembly=Microsoft.WebAnalytics";

            doc.Root.Add(new XAttribute(XNamespace.Xmlns + "mwa", mwa));

            const string ALOName = "{http://schemas.microsoft.com/winfx/2006/xaml/presentation}Application.ApplicationLifetimeObjects";

            XElement alo = doc.Root.Element(ALOName);

            if (alo == null)
            {
                alo = new XElement(ALOName);

                doc.Root.Add(alo);
            }

            const string WASName = "{clr-namespace:Microsoft.WebAnalytics;assembly=Microsoft.WebAnalytics}WebAnalyticsService";

            if (alo.Element(WASName) == null)
            {
                var was = new XElement(WASName);

                alo.Add(was);

                var newXaml = GetXamlText(doc);

                startPoint.ReplaceText(textDocument.EndPoint, newXaml, (int)vsFindOptions.vsFindOptionsFromStart);

                window.Close(vsSaveChanges.vsSaveChangesYes);
            }
            else
            {
                window.Close(vsSaveChanges.vsSaveChangesNo);
            }
        }
        #region Implementation
        /// <summary>
        /// Get the UTF-8 formatted XAML Text for the Application
        /// </summary>
        /// <param name="doc">the XML Document</param>
        /// <returns>the UTF-8 text</returns>
        private static string GetXamlText(XDocument doc)
        {
            var output = new StringWriterWithEncoding(Encoding.UTF8);

            var settings = new XmlWriterSettings
            {
                Indent = true,
                NewLineOnAttributes = true
            };

            var writer = XmlTextWriter.Create(output, settings);

            doc.Save(writer);

            writer.Flush();

            var newXaml = output.GetStringBuilder().ToString();

            return newXaml;
        }
        #endregion
    }
}
